package com.bf.electroplating.service.impl;

import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bf.electroplating.mapper.InflowManagementMapper;
import com.bf.electroplating.pojo.entity.ComCompany;
import com.bf.electroplating.pojo.entity.InflowManagement;
import com.bf.electroplating.pojo.entity.SewageWarningConfig;
import com.bf.electroplating.pojo.vo.ResultVO;
import com.bf.electroplating.pojo.vo.SelectVo;
import com.bf.electroplating.pojo.vo.inflowManagement.*;
import com.bf.electroplating.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.v3.oas.models.security.SecurityScheme;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 进水管控管理表 服务实现类
 * </p>
 *
 * @author gzd
 * @since 2025-08-21
 */
@Service
public class InflowManagementServiceImpl extends ServiceImpl<InflowManagementMapper, InflowManagement> implements IInflowManagementService {

    @Resource
    private ComCompanyService comCompanyService;
    @Resource
    private PubAttachmentService pubAttachmentService;
    @Resource
    private ISewageWarningConfigService sewageWarningConfigService;
    @Resource
    private PubParamDictionaryService pubParamDictionaryService;

    @Override
    public ResultVO < Page < InflowManagementVO > > pageList ( InflowManagementQueryDTO queryDTO ) {
        Page < InflowManagement > page = new Page <> ( queryDTO.getPageNum () , queryDTO.getPageSize () );

        LambdaQueryWrapper< InflowManagement > wrapper = new LambdaQueryWrapper <> ();

        if ( org.apache.commons.lang3.StringUtils.isNotBlank ( queryDTO.getCompanyId () ) ) {
            wrapper.eq ( InflowManagement::getCompanyId , queryDTO.getCompanyId () );
        }

        if ( StringUtils.isNotBlank ( queryDTO.getWasteWaterType () ) ) {
            wrapper.eq ( InflowManagement::getWasteWaterType , queryDTO.getWasteWaterType () );
        }

        if ( queryDTO.getTime () !=null ) {
            wrapper.eq ( InflowManagement::getDetectionDate , queryDTO.getTime () );
        }


        wrapper.orderByDesc ( InflowManagement::getCreateTime );

        Page < InflowManagement > resultPage = this.page ( page , wrapper );

        // 转换为VO
        Page < InflowManagementVO > voPage = new Page <> ();
        BeanUtils.copyProperties ( resultPage , voPage , "records" );
        List < InflowManagementVO > voList = new ArrayList<>();
        for ( InflowManagement entity : resultPage.getRecords () ) {
            InflowManagementVO vo = new InflowManagementVO ();
            BeanUtils.copyProperties ( entity , vo );
            vo.setStatus(getInflowStatus(entity));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            // 格式化日期
            vo.setCreateTime(sdf.format(entity.getCreateTime()));
            voList.add ( vo );
        }
        voPage.setRecords ( voList );
        return ResultVO.ok ( voPage );
    }

    private String getInflowStatus(InflowManagement vo) {
        String status = "正常";
        if ("1".equals(vo.getMonitorTotalNickel())&&vo.getTotalNickelThreshold().compareTo(vo.getTotalNickelValue()!=null?vo.getTotalNickelValue():new BigDecimal("0.0"))<0){
            status="异常";
        }
        if ("1".equals(vo.getMonitorHexavalentChromium())&&vo.getHexavalentChromiumThreshold().compareTo(vo.getHexavalentChromiumValue()!=null?vo.getHexavalentChromiumValue():new BigDecimal("0.0"))<0){
            status="异常";
        }
        if ("1".equals(vo.getMonitorTotalChromium())&&vo.getTotalChromiumThreshold().compareTo(vo.getTotalChromiumValue()!=null?vo.getHexavalentChromiumValue():new BigDecimal("0.0"))<0){
            status="异常";
        }
        return status;
    }

    @Override
    @Transactional( rollbackFor = Exception.class )
    public ResultVO < String > saveData ( InflowManagementDTO dto ) {
        InflowManagement inflowManagement = new InflowManagement ();
        BeanUtils.copyProperties ( dto , inflowManagement );
        SewageWarningConfig sewageWarningConfig=sewageWarningConfigService
                .getOne(new LambdaQueryWrapper<SewageWarningConfig>()
                        .eq(SewageWarningConfig::getCompanyId,dto.getCompanyId())
                        .eq(SewageWarningConfig::getWasteWaterType,dto.getWasteWaterType()),false);
        if (sewageWarningConfig==null){
            return ResultVO.fail("请设置本企业本污水类型的预警阈值用于判断状态");
        }
        inflowManagement.setTotalNickelThreshold( sewageWarningConfig.getTotalNickelThreshold() );
        inflowManagement.setTotalChromiumThreshold( sewageWarningConfig.getTotalChromiumThreshold() );
        inflowManagement.setHexavalentChromiumThreshold(sewageWarningConfig.getHexavalentChromiumThreshold() );
        inflowManagement.setMonitorTotalNickel( sewageWarningConfig.getMonitorTotalNickel() );
        inflowManagement.setMonitorTotalChromium( sewageWarningConfig.getMonitorTotalChromium() );
        inflowManagement.setMonitorHexavalentChromium( sewageWarningConfig.getMonitorHexavalentChromium() );
        saveOrUpdate ( inflowManagement );
        return ResultVO.ok ( null , "保存成功" );
    }

    @Override
    @Transactional ( rollbackFor = Exception.class )
    public ResultVO < String > delete ( List < String > ids ) {
        if ( ids == null || ids.isEmpty () ) {
            return ResultVO.fail ( "ID不能为空" );
        }

        this.removeByIds ( ids );
        return ResultVO.ok ( null , "删除成功" );
    }

    @Override
    public ResultVO < InflowManagementVO > getDetail ( String id ) {
        if ( StringUtils.isBlank ( id ) ) {
            return ResultVO.fail ( "ID不能为空" );
        }
        InflowManagement entity = this.getById ( id );
        if ( entity == null ) {
            return ResultVO.fail ( "记录不存在" );
        }

        Map < String,String > companyMap = comCompanyService.list ().stream ().collect ( Collectors.toMap ( ComCompany::getId , ComCompany::getCompanyName ) );

        InflowManagementVO vo = new InflowManagementVO ();
        BeanUtils.copyProperties ( entity , vo );

        return ResultVO.ok ( vo );
    }

    @Override
    public ResultVO<List<InflowManagementAnalysisVO>> getAnalysis(InflowManagementAnalysisDTO inflowManagementAnalysisDTO) {
        List<InflowManagement> inflowManagements=this.list(new LambdaQueryWrapper<InflowManagement>()
        .in(InflowManagement::getCompanyId,inflowManagementAnalysisDTO.getCompanyId())
                .eq(InflowManagement::getWasteWaterType,inflowManagementAnalysisDTO.getWasteWaterType())
                .ge(InflowManagement::getCreateTime,inflowManagementAnalysisDTO.getTimes().get(0))
                .le(InflowManagement::getCreateTime,inflowManagementAnalysisDTO.getTimes().get(1)));
        if (inflowManagements==null || inflowManagements.size()==0){
            return ResultVO.fail("无数据");
        }
        Map<String,List<InflowManagement>> map=inflowManagements.stream().collect ( Collectors.groupingBy ( InflowManagement::getCompanyName ) );
        LocalDate end=inflowManagementAnalysisDTO.getTimes().get(1);
        List<InflowManagementAnalysisVO> vos=new ArrayList<>();
        for (String companyName : map.keySet() ) {
            LocalDate index=inflowManagementAnalysisDTO.getTimes().get(0);
            InflowManagementAnalysisVO  vo=new InflowManagementAnalysisVO ();
            vo.setName( companyName );
            List<InflowManagement> list=map.get(companyName);
            List<List<String>> finalValue=new ArrayList<>();
            while (index.isBefore(end)) {
                List<String> dataValueMap=new ArrayList<>();
                LocalDate finalIndex = index;
                List<InflowManagement> todayDate=list.stream().filter(i->i.getDetectionDate()
                        .compareTo(finalIndex)==0).toList();
                if (todayDate==null || todayDate.size()==0){
                    dataValueMap.add(index.format(DateTimeFormatter.ISO_DATE));
                    dataValueMap.add("0");
                }else {
                    BigDecimal value=new BigDecimal(0);
                    switch (inflowManagementAnalysisDTO.getDetectabilityFactor()) {
                        case "1" :
                            value=todayDate.get(0).getHexavalentChromiumValue();
                            break;
                        case "2" :
                            value=todayDate.get(0).getTotalChromiumValue();
                            break;
                        case "3" :
                            value=todayDate.get(0).getTotalNickelValue();
                            break;
                    };
                    if (value==null){
                        value=new BigDecimal(0);
                    }
                    dataValueMap.add(index.format(DateTimeFormatter.ISO_DATE));
                    dataValueMap.add(value.toPlainString());
                }
                finalValue.add(dataValueMap);
                index=index.plusDays(1);
            }
            vo.setCoordinates(finalValue);
            vos.add(vo);
        }
        return ResultVO.ok ( vos );
    }

    @Override
    public ResultVO<List<InflowManagementAnalysisNeoVO>> getAnalysisNeo(InflowManagementAnalysisNeoDTO inflowManagementAnalysisDTO) {
        LambdaQueryWrapper<InflowManagement> inflowManagementLambdaQueryWrapper=new LambdaQueryWrapper<InflowManagement>()
                .eq(InflowManagement::getCompanyId,inflowManagementAnalysisDTO.getCompanyId())
                .ge(InflowManagement::getCreateTime,inflowManagementAnalysisDTO.getTimes().get(0))
                .le(InflowManagement::getCreateTime,inflowManagementAnalysisDTO.getTimes().get(1));
        if (!StringUtils.isEmpty(inflowManagementAnalysisDTO.getWasteWaterType())) {
            inflowManagementLambdaQueryWrapper.eq(InflowManagement::getWasteWaterType,inflowManagementAnalysisDTO.getWasteWaterType());
        }
        List<InflowManagement> inflowManagements=this.list(inflowManagementLambdaQueryWrapper);
//        if (inflowManagements==null || inflowManagements.size()==0){
//            return ResultVO.fail("无数据");
//        }
        List<SelectVo> selectVos= pubParamDictionaryService.getParamList("FSLX").getData();
        LambdaQueryWrapper<SewageWarningConfig> sewageWarningConfigLambdaQueryWrapper=new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(inflowManagementAnalysisDTO.getWasteWaterType())) {
            sewageWarningConfigLambdaQueryWrapper.eq(SewageWarningConfig::getWasteWaterType, inflowManagementAnalysisDTO.getWasteWaterType());
        }
        if (!StringUtils.isEmpty(inflowManagementAnalysisDTO.getCompanyId())) {
            sewageWarningConfigLambdaQueryWrapper.eq(SewageWarningConfig::getCompanyId, inflowManagementAnalysisDTO.getCompanyId());
        }
        List<SewageWarningConfig> sewageWarningConfigs=sewageWarningConfigService.list(sewageWarningConfigLambdaQueryWrapper);
        LocalDate end=inflowManagementAnalysisDTO.getTimes().get(1);
        List<InflowManagementAnalysisNeoVO> vos=new ArrayList<>();
            LocalDate index=inflowManagementAnalysisDTO.getTimes().get(0);
            InflowManagementAnalysisNeoVO  vo=new InflowManagementAnalysisNeoVO ();
            List<InflowManagement> list=inflowManagements;
            Map<String,List<String>>  finalValue=new HashMap<>();
            List<String> typeString=new ArrayList<>();
            if (!StringUtils.isEmpty(inflowManagementAnalysisDTO.getWasteWaterType())) {
//                typeString.add(wasterWaterName+"(六价铬)");
//                typeString.add(wasterWaterName+"(总铬)");
//                typeString.add(wasterWaterName+"(总镍)");
                typeString.add(inflowManagementAnalysisDTO.getWasteWaterType()+"-1");
                typeString.add(inflowManagementAnalysisDTO.getWasteWaterType()+"-2");
                typeString.add(inflowManagementAnalysisDTO.getWasteWaterType()+"-3");
            }else {
                for (SewageWarningConfig selectVo : sewageWarningConfigs) {
                    String code=selectVo.getWasteWaterType();
                    typeString.add(code+"-1");
                    typeString.add(code+"-2");
                    typeString.add(code+"-3");
                }
            }
            List<Map<String,String>> dataValueMap=new ArrayList<>();
            List<String> dates=new ArrayList<>();
            while (!index.isAfter(end)) {
                LocalDate finalIndex = index;
                List<InflowManagement> todayDate;
                dates.add(index.format(DateTimeFormatter.ISO_DATE));
                for (String code : typeString) {
                    List<String> dataValue=finalValue.get(codeToDataValue(code,selectVos));
                    if (dataValue==null){
                        dataValue=new ArrayList<>();
                        finalValue.put(codeToDataValue(code,selectVos),dataValue);
                    }
                    String waterType=code.split("-")[0];
                    todayDate = list.stream().filter(i -> i.getDetectionDate()
                            .compareTo(finalIndex) == 0&&waterType.equals(i.getWasteWaterType())).toList();
                        if ( todayDate.isEmpty()) {
                                dataValue.add("0");
                        } else {
                            String favorType=code.split("-")[1];
                         switch (favorType) {
                        case "1":

                             dataValue.add( todayDate.get(0).getHexavalentChromiumValue()!=null?todayDate.get(0).getHexavalentChromiumValue()+"":"0");
                            break;
                        case "2":
                            dataValue.add( todayDate.get(0).getTotalChromiumValue()!=null?todayDate.get(0).getTotalChromiumValue()+"":"0");
                            break;
                        case "3":
                            dataValue.add( todayDate.get(0).getTotalNickelValue()!=null?todayDate.get(0).getTotalNickelValue()+"":"0");
                            break;
                         }
//                        dataValueMap.add(value.toPlainString());
                        }
                    }
                index = index.plusDays(1);
            }
        vo.setDate(dates);
            vo.setCoordinates(finalValue);
            vos.add(vo);
        return ResultVO.ok(vos);
    }

    @Override
    public ResultVO<List<InflowManagementAnalysisNeoVO>> getAnalysisWithFactor(InflowManagementAnalysisFactorDTO inflowManagementAnalysisDTO) {
        LambdaQueryWrapper<InflowManagement> inflowManagementLambdaQueryWrapper=new LambdaQueryWrapper<InflowManagement>()
                .ge(InflowManagement::getCreateTime,inflowManagementAnalysisDTO.getTimes().get(0))
                .le(InflowManagement::getCreateTime,inflowManagementAnalysisDTO.getTimes().get(1));
        if (!StringUtils.isEmpty(inflowManagementAnalysisDTO.getWasteWaterType())) {
            inflowManagementLambdaQueryWrapper.eq(InflowManagement::getWasteWaterType,inflowManagementAnalysisDTO.getWasteWaterType());
        }
        List<InflowManagement> inflowManagements=this.list(inflowManagementLambdaQueryWrapper);
        LambdaQueryWrapper<SewageWarningConfig> sewageWarningConfigLambdaQueryWrapper=new LambdaQueryWrapper<>();
        sewageWarningConfigLambdaQueryWrapper.eq(SewageWarningConfig::getWasteWaterType,inflowManagementAnalysisDTO.getWasteWaterType());
        if ("1".equals(inflowManagementAnalysisDTO.getFactorCode())) {
            sewageWarningConfigLambdaQueryWrapper.eq(SewageWarningConfig::getMonitorHexavalentChromium,"1");
        }
        if ("2".equals(inflowManagementAnalysisDTO.getFactorCode())) {
            sewageWarningConfigLambdaQueryWrapper.eq(SewageWarningConfig::getMonitorTotalChromium,"1");
        }
        if ("3".equals(inflowManagementAnalysisDTO.getFactorCode())) {
            sewageWarningConfigLambdaQueryWrapper.eq(SewageWarningConfig::getMonitorTotalNickel,"1");
        }
        List<SewageWarningConfig> sewageWarningConfigs=sewageWarningConfigService.list(sewageWarningConfigLambdaQueryWrapper);
        LocalDate end=inflowManagementAnalysisDTO.getTimes().get(1);
        List<InflowManagementAnalysisNeoVO> vos=new ArrayList<>();
        LocalDate index=inflowManagementAnalysisDTO.getTimes().get(0);
        InflowManagementAnalysisNeoVO  vo=new InflowManagementAnalysisNeoVO ();
        List<InflowManagement> list=inflowManagements;
        Map<String,List<String>>  finalValue=new HashMap<>();
        List<String> typeString=new ArrayList<>();
        for (SewageWarningConfig selectVo : sewageWarningConfigs) {
            typeString.add(selectVo.getCompanyName());
        }
        List<Map<String,String>> dataValueMap=new ArrayList<>();
        List<String> dates=new ArrayList<>();
        while (!index.isAfter(end)) {
            LocalDate finalIndex = index;
            List<InflowManagement> todayDate;

            dates.add(index.format(DateTimeFormatter.ISO_DATE));
            for (String code : typeString) {
                List<String> dataValue=finalValue.get(code);
                if (dataValue==null){
                    dataValue=new ArrayList<>();
                    finalValue.put(code,dataValue);
                }
                String waterType=inflowManagementAnalysisDTO.getWasteWaterType();
                todayDate = list.stream().filter(i -> i.getDetectionDate()
                        .compareTo(finalIndex) == 0&&waterType.equals(i.getWasteWaterType())&&code.equals(i.getCompanyName())).toList();
                if ( todayDate.isEmpty()) {
                    dataValue.add("0");
                } else {
                    String favorType=inflowManagementAnalysisDTO.getFactorCode();
                    switch (favorType) {
                        case "1":
                            dataValue.add( todayDate.get(0).getHexavalentChromiumValue()!=null?todayDate.get(0).getHexavalentChromiumValue()+"":"0");
                            break;
                        case "2":
                            dataValue.add( todayDate.get(0).getTotalChromiumValue()!=null?todayDate.get(0).getTotalChromiumValue()+"":"0");
                            break;
                        case "3":
                            dataValue.add( todayDate.get(0).getTotalNickelValue()!=null?todayDate.get(0).getTotalNickelValue()+"":"0");
                            break;
                    }
                }
            }
            index = index.plusDays(1);
        }
        vo.setDate(dates);
        vo.setCoordinates(finalValue);
        vos.add(vo);
        return ResultVO.ok(vos);
    }

    private String codeToDataValue(String code,List<SelectVo>  selectVos){
        String result="";
        String waterCode=code.split("-")[0];
        String factorCode=code.split("-")[1];
        String waterMame=selectVos.stream().filter(i->waterCode.equals(i.getId())).findFirst().get().getName();
        switch (factorCode){
            case "1":
                result = waterMame+"(六价铬)";
                            return result;
                        case "2":
                            result = waterMame+"(总铬)";
                            return result;
                        case "3":
                            result = waterMame+"(总镍)";
                            return result;
        }
        return result;
    }

}
